#ifndef __TIME_H__
#define __TIME_H__
#include "libs/lib.h"
#include "libs/io.h"
#include "kernel/interrupt/interrupt.h"
#include "libs/queue.h"
#include "kernel/task/task.h"
#define CMOS_READ(addr) \
({ \
    io_out8(PORT_RTC_INDEX,0x80 | addr); \
    io_in8(PORT_RTC_DATA); \ 
}) \


struct time
{
	int second;	//00
	int minute;	//02
	int hour;	//04
	int day;	//07
	int month;	//08
	int year;	//09+32
};




extern "C" void delayMicro(uint64_t delay);


class TimerTask
{
private:
    /* data */
public:
    uint64_t expire_time;
    
    uint64_t internalTime;
    TimerTask(uint64_t/* args */);
    ~TimerTask();
    void handler();
};






class HpetTimer
{
private:
    /* data */
public:
    uint8_t* hpetRegsAddr;
   
    HpetTimer(/* args */);
    ~HpetTimer();
   
    void getHpetACPITable();


};



class ApicTimer{

private:


public:
    uint64_t x2apichz;
    ApicTimer(uint64_t number);    
    ~ApicTimer();

};



#define	BCD2BIN(value)	(((value) & 0xf) + ((value) >> 4 ) * 10)
#define GETTIMESTATP(year,month,day,hour,minute,second) \
BCD2BIN(value)*60*60*60*365

#define ISONESECOND \
((BCD2BIN(time.minute) - BCD2BIN(lastTime.minute) == 0)  \
&& ((BCD2BIN(time.second) - BCD2BIN(lastTime.second)) >=30)) \
|| ((BCD2BIN(time.minute) - BCD2BIN(lastTime.minute)) == 1) \
&& \
(((BCD2BIN(time.second) + 60 - BCD2BIN(lastTime.second)) >=30)) \
? 1 : 0;

class TimeManager : public interrupthandler,public SoftInterruptHandler
{
private:
    /* data */
public:
    time lastTime;
    static TimeManager* timem;
    HpetTimer* hpet;
    uint64_t cpuhz;
    uint64_t x2apichz;
    uint64_t Quantun;
    ApicTimer* apict;
    uint64_t timeCount;
    Queue<TimerTask> taskQueue;
    int getCMOSRTC(time* time);
    void logTime();
    TimeManager(/* args */);
    ~TimeManager();
    void initApicTimer();
    int isOneSecond();
    virtual StackFrame* handleInterrupt(StackFrame* fs);
    virtual void handleSoftInterrupt();
    void addTimerTask(TimerTask* task);
    void delTimerTask(TimerTask* task);




    //cpuhz
    void initHz();
};


#define TIMEMANAGER \
TimeManager::timem

#endif